import 'dart:math' as math;
import 'package:intl/intl.dart';
import 'package:moonmate/models/pregnancy_prep_model.dart';
import 'package:moonmate/models/period_model.dart';
import 'package:moonmate/services/shared_preferences_service.dart';

class PregnancyPrepService {
  static final PregnancyPrepService _instance = PregnancyPrepService._internal();
  SharedPreferencesService? _prefsService;

  factory PregnancyPrepService() {
    return _instance;
  }

  PregnancyPrepService._internal() {
    _prefsService = SharedPreferencesService();
    _prefsService?.initialize();
  }

  // 记录基础体温
  Future<BasalBodyTemperature> recordTemperature({
    required DateTime date,
    required double temperature,
    String? timeRecorded,
    String? notes,
    required int userId,
  }) async {
    final timeRecordedValue = timeRecorded ?? DateFormat('HH:mm').format(DateTime.now());
    final tempRecord = BasalBodyTemperature(
      id: DateTime.now().millisecondsSinceEpoch,
      date: date,
      temperature: temperature,
      timeRecorded: timeRecordedValue,
      notes: notes,
      userId: userId,
    );

    final data = tempRecord.toMap();
    await _prefsService!.addObjectToList(SharedPreferencesService.keyBBTRecords, data);
    
    // 尝试分析是否为排卵日
    await _analyzeOvulationDays(userId);
    
    return tempRecord;
  }

  // 记录排卵试纸结果
  Future<OvulationTest> recordOvulationTest({
    required DateTime date,
    required String result,
    String? imagePath,
    int lineIntensity = 5,
    String? notes,
    required int userId,
  }) async {
    final testRecord = OvulationTest(
      id: DateTime.now().millisecondsSinceEpoch,
      date: date,
      result: result,
      imagePath: imagePath,
      lineIntensity: lineIntensity,
      notes: notes,
      userId: userId,
    );

    await _prefsService!.addObjectToList(SharedPreferencesService.keyOvulationTests, testRecord.toMap());
    
    // 如果是强阳性或阳性，可能是LH峰值，更新相关分析
    if (testRecord.isPeakDay()) {
      await _updateOvulationAnalysis(userId, date);
    }
    
    return testRecord;
  }

  // 记录宫颈粘液情况
  Future<CervicalMucus> recordCervicalMucus({
    required DateTime date,
    required String consistency,
    String color = 'clear',
    String amount = 'medium',
    String? notes,
    required int userId,
  }) async {
    final mucusRecord = CervicalMucus(
      id: DateTime.now().millisecondsSinceEpoch,
      date: date,
      consistency: consistency,
      color: color,
      amount: amount,
      notes: notes,
      userId: userId,
    );

    await _prefsService!.addObjectToList(SharedPreferencesService.keyCMRecords, mucusRecord.toMap());
    return mucusRecord;
  }

  // 记录同房情况
  Future<Intercourse> recordIntercourse({
    required DateTime date,
    String? time,
    int satisfaction = 3,
    bool protectionUsed = false,
    String? notes,
    required int userId,
  }) async {
    final intercourseRecord = Intercourse(
      id: DateTime.now().millisecondsSinceEpoch,
      date: date,
      time: time,
      satisfaction: satisfaction,
      protectionUsed: protectionUsed,
      notes: notes,
      userId: userId,
    );

    await _prefsService!.addObjectToList(SharedPreferencesService.keyIntercourse, intercourseRecord.toMap());
    return intercourseRecord;
  }

  // 记录叶酸补充情况
  Future<FolicAcidIntake> recordFolicAcid({
    required DateTime date,
    double amount = 400.0,
    bool taken = true,
    String? notes,
    required int userId,
  }) async {
    final folicRecord = FolicAcidIntake(
      id: DateTime.now().millisecondsSinceEpoch,
      date: date,
      amount: amount,
      taken: taken,
      notes: notes,
      userId: userId,
    );

    await _prefsService!.addObjectToList(SharedPreferencesService.keyFolicAcid, folicRecord.toMap());
    
    // 更新叶酸依从率
    await _updateFolicAcidComplianceRate(userId);
    
    return folicRecord;
  }

  // 预测排卵和易孕期
  Future<FertilityPrediction> predictFertility({
    required int userId,
    int daysAhead = 30,
  }) async {
    // 获取用户的周期信息和历史数据
    final userProfile = _prefsService?.getObject(SharedPreferencesService.keyUser);
    final allPeriods = _prefsService?.getObjectList(SharedPreferencesService.keyPeriods) ?? [];
    final periods = allPeriods
        .where((p) => p['user_id'].toString() == userId.toString())
        .map((p) => Period.fromMap(p))
        .toList();
    
    final allTemps = _prefsService?.getObjectList(SharedPreferencesService.keyBBTRecords) ?? [];
    final temperatures = allTemps
        .where((t) => t['user_id'].toString() == userId.toString())
        .take(60)
        .toList();
    
    final allTests = _prefsService?.getObjectList(SharedPreferencesService.keyOvulationTests) ?? [];
    final ovulationTests = allTests
        .where((t) => t['user_id'].toString() == userId.toString())
        .take(30)
        .toList();
    
    final allMucus = _prefsService?.getObjectList(SharedPreferencesService.keyCMRecords) ?? [];
    final mucusRecords = allMucus
        .where((m) => m['user_id'].toString() == userId.toString())
        .take(30)
        .toList();

    // 确定最近一次经期开始日期
    DateTime lastPeriodStart;
    if (periods.isNotEmpty) {
      periods.sort((a, b) => b.startDate.compareTo(a.startDate));
      lastPeriodStart = periods.first.startDate;
    } else {
      // 安全访问userProfile的lastPeriodDate属性
      if (userProfile != null && userProfile.containsKey('lastPeriodDate')) {
        lastPeriodStart = DateTime.parse(userProfile['lastPeriodDate'].toString());
      } else {
        lastPeriodStart = DateTime.now().subtract(Duration(days: 14));
      }
    }

    // 计算平均周期长度
    double avgCycleLength = 28.0; // 默认值
    if (periods.length >= 2) {
      double totalDays = 0;
      for (int i = 0; i < periods.length - 1; i++) {
        totalDays += periods[i].startDate.difference(periods[i + 1].startDate).inDays;
      }
      avgCycleLength = totalDays / (periods.length - 1);
    } else if (userProfile != null && userProfile.containsKey('cycleLength')) {
      avgCycleLength = double.tryParse(userProfile['cycleLength'].toString()) ?? 28.0;
    }

    // 预测下次经期开始日期
    final nextPeriodDate = lastPeriodStart.add(Duration(days: avgCycleLength.round()));
    
    // 预测排卵日期（通常在下次经期前14天左右）
    DateTime predictedOvulationDate = nextPeriodDate.subtract(Duration(days: 14));
    
    // 使用基础体温数据优化排卵预测
    if (temperatures.isNotEmpty) {
      predictedOvulationDate = _optimizeOvulationPredictionWithTemperature(
        predictedOvulationDate, 
        temperatures
      );
    }
    
    // 使用排卵试纸数据优化预测
    if (ovulationTests.isNotEmpty) {
      predictedOvulationDate = _optimizeOvulationPredictionWithTests(
        predictedOvulationDate, 
        ovulationTests
      );
    }
    
    // 使用宫颈粘液数据优化预测
    if (mucusRecords.isNotEmpty) {
      predictedOvulationDate = _optimizeOvulationPredictionWithMucus(
        predictedOvulationDate, 
        mucusRecords
      );
    }

    // 计算易孕期窗口（排卵前5天到排卵后1天）
    final fertileWindow = <DateTime>[];
    for (int i = 5; i >= -1; i--) {
      fertileWindow.add(predictedOvulationDate.subtract(Duration(days: i)));
    }

    // 确定最佳同房日（通常是排卵前1天）
    final bestIntercourseDay = predictedOvulationDate.subtract(Duration(days: 1));

    // 计算峰值受孕概率
    double peakProbability = _calculatePeakProbability(
      temperatures,
      ovulationTests,
      mucusRecords,
      periods.length,
    );

    // 计算预测置信度
    int predictionConfidence = _calculateConfidence(
      periods,
      temperatures,
      ovulationTests,
      mucusRecords,
    );

    // 生成推荐建议
    String recommendation = _generateRecommendation(
      predictedOvulationDate,
      fertileWindow,
      peakProbability,
      predictionConfidence,
    );

    return FertilityPrediction(
      predictedOvulationDate: predictedOvulationDate,
      fertileWindow: fertileWindow,
      bestIntercourseDay: bestIntercourseDay,
      peakProbability: peakProbability,
      predictionConfidence: predictionConfidence,
      predictionFactors: [
        if (periods.isNotEmpty) '周期历史',
        if (temperatures.isNotEmpty) '基础体温',
        if (ovulationTests.isNotEmpty) '排卵试纸',
        if (mucusRecords.isNotEmpty) '宫颈粘液',
      ],
      recommendation: recommendation,
    );
  }

  // 获取备孕知识库文章
  Future<List<Map<String, dynamic>>> getKnowledgeArticles(String category, {int limit = 10, int offset = 0}) async {
    try {
      final allArticles = _prefsService!.getObjectList(SharedPreferencesService.keyKnowledgeArticles);
      
      // 过滤分类
      final filteredArticles = allArticles
          .where((article) => article['category'] == category)
          .toList();
      
      // 按创建时间排序（降序）
      filteredArticles.sort((a, b) {
        final dateA = DateTime.parse(a['created_at'] as String);
        final dateB = DateTime.parse(b['created_at'] as String);
        return dateB.compareTo(dateA);
      });
      
      // 分页
      final startIndex = offset;
      final endIndex = (offset + limit) > filteredArticles.length ? filteredArticles.length : (offset + limit);
      
      if (startIndex >= filteredArticles.length) {
        return [];
      }
      
      return filteredArticles.sublist(startIndex, endIndex);
    } catch (e) {
      // 获取知识文章列表失败
      return [];
    }
  }

  // 获取单篇知识库文章
  Future<Map<String, dynamic>?> getKnowledgeArticle(String articleId) async {
    try {
      final articles = _prefsService!.getObjectList(SharedPreferencesService.keyKnowledgeArticles);
      final article = articles.firstWhere(
        (item) => item['id'] == articleId,
        orElse: () => <String, dynamic>{}, 
      );
      
      if (article.isNotEmpty) {
        // 异步更新阅读次数，不阻塞返回
        saveKnowledgeArticleReadStatus(articleId);
        return article;
      }
      return null;
    } catch (e) {
      // 获取知识文章失败
      return null;
    }
  }

  // 更新知识文章阅读状态
  Future<void> saveKnowledgeArticleReadStatus(String articleId) async {
    try {
      final articles = _prefsService!.getObjectList(SharedPreferencesService.keyKnowledgeArticles);
      final updatedArticles = articles.map((article) {
        if (article['id'] == articleId) {
          final updatedArticle = Map<String, dynamic>.from(article);
          updatedArticle['read_count'] = (updatedArticle['read_count'] as int? ?? 0) + 1;
          updatedArticle['last_read_at'] = DateTime.now().toIso8601String();
          return updatedArticle;
        }
        return article;
      }).toList();
      
      await _prefsService!.setObjectList(SharedPreferencesService.keyKnowledgeArticles, updatedArticles);
    } catch (e) {
      // 更新知识文章阅读状态失败
    }
  }
  
  // 记录基础体温（兼容旧API）
  Future<BasalBodyTemperature> recordBasalBodyTemperature({
    required DateTime date,
    required double temperature,
    String? timeRecorded,
    String? notes,
    required int userId,
  }) async {
    // 直接调用现有的recordTemperature方法
    return await recordTemperature(
      date: date,
      temperature: temperature,
      timeRecorded: timeRecorded,
      notes: notes,
      userId: userId,
    );
  }

  // 预测排卵周期
  Future<List<Map<String, dynamic>>> predictOvulationPeriod(DateTime startDate, DateTime endDate) async {
    try {
      // 在这里实现排卵预测算法
      // 简化版实现：基于基础体温、宫颈粘液等数据进行预测
      
      // 获取基础体温数据
      final allTemps = _prefsService!.getObjectList(SharedPreferencesService.keyBBTRecords);
      allTemps.where((t) {
        final date = DateTime.tryParse(t['date'] ?? '');
        return date != null && date.isAfter(startDate.subtract(Duration(days: 1))) && date.isBefore(endDate.add(Duration(days: 1)));
      }).toList();
      
      // 获取宫颈粘液数据
      final allMucus = _prefsService!.getObjectList(SharedPreferencesService.keyCMRecords);
      allMucus.where((m) {
        final date = DateTime.tryParse(m['date'] ?? '');
        return date != null && date.isAfter(startDate.subtract(Duration(days: 1))) && date.isBefore(endDate.add(Duration(days: 1)));
      }).toList();
      
      // 获取排卵测试数据
      final allTests = _prefsService!.getObjectList(SharedPreferencesService.keyOvulationTests);
      allTests.where((t) {
        final date = DateTime.tryParse(t['date'] ?? '');
        return date != null && date.isAfter(startDate.subtract(Duration(days: 1))) && date.isBefore(endDate.add(Duration(days: 1)));
      }).toList();
      
      // 构建预测结果
      final predictions = <Map<String, dynamic>>[];
      
      // 这里应该有更复杂的算法，但为了演示，我们只返回一个示例预测
      // 假设在周期中间附近排卵
      final midDate = startDate.add(Duration(days: (endDate.difference(startDate).inDays / 2).round()));
      
      predictions.add({
        'date': midDate.toIso8601String(),
        'probability': 0.8,
        'type': 'ovulation',
        'note': '基于周期计算的预测排卵日',
      });
      
      // 计算易孕期（排卵日前后几天）
      for (int i = -2; i <= 1; i++) {
        if (i != 0) { // 跳过已经添加的排卵日
          final fertileDate = midDate.add(Duration(days: i));
          predictions.add({
            'date': fertileDate.toIso8601String(),
            'probability': i == -1 ? 0.7 : 0.6,
            'type': 'fertile',
            'note': '易孕期',
          });
        }
      }
      
      return predictions;
    } catch (e) {
      // 预测排卵周期失败，返回空列表
      return [];
    }
  }

  // 更新用户健康指标
  Future<bool> updateHealthMetrics(String userId, Map<String, dynamic> metrics) async {
    try {
      // 更新用户健康指标
      final userData = _prefsService!.getObject(SharedPreferencesService.keyUser);
      if (userData != null) {
        final updatedData = { ...userData, ...metrics, 'updated_at': DateTime.now().toIso8601String() };
        return await _prefsService!.saveObject(SharedPreferencesService.keyUser, updatedData);
      }
      return false;
    } catch (e) {
      // 更新健康指标失败
      return false;
    }
  }

  // 获取备孕日历数据
  Future<List<FertilityCalendarDay>> getFertilityCalendar({
    required DateTime startDate,
    required DateTime endDate,
    required int userId,
  }) async {
    final calendarDays = <FertilityCalendarDay>[];
    final prediction = await predictFertility(userId: userId);
    
    // 获取日期范围内的各种记录
    final allTemps = _prefsService!.getObjectList(SharedPreferencesService.keyBBTRecords);
    final temperatures = allTemps.where((t) => 
      t['user_id'] == userId &&
      DateTime.tryParse(t['date'] ?? '') != null &&
      DateTime.parse(t['date']).isAfter(startDate.subtract(Duration(days: 1))) &&
      DateTime.parse(t['date']).isBefore(endDate.add(Duration(days: 1)))
    ).toList();
    
    final allTests = _prefsService!.getObjectList(SharedPreferencesService.keyOvulationTests);
    final ovulationTests = allTests.where((t) => 
      t['user_id'] == userId &&
      DateTime.tryParse(t['date'] ?? '') != null &&
      DateTime.parse(t['date']).isAfter(startDate.subtract(Duration(days: 1))) &&
      DateTime.parse(t['date']).isBefore(endDate.add(Duration(days: 1)))
    ).toList();
    
    final allMucus = _prefsService!.getObjectList(SharedPreferencesService.keyCMRecords);
    final mucusRecords = allMucus.where((m) => 
      m['user_id'] == userId &&
      DateTime.tryParse(m['date'] ?? '') != null &&
      DateTime.parse(m['date']).isAfter(startDate.subtract(Duration(days: 1))) &&
      DateTime.parse(m['date']).isBefore(endDate.add(Duration(days: 1)))
    ).toList();
    
    final allIntercourse = _prefsService!.getObjectList(SharedPreferencesService.keyIntercourse);
    final intercourseRecords = allIntercourse.where((i) => 
      i['user_id'] == userId &&
      DateTime.tryParse(i['date'] ?? '') != null &&
      DateTime.parse(i['date']).isAfter(startDate.subtract(Duration(days: 1))) &&
      DateTime.parse(i['date']).isBefore(endDate.add(Duration(days: 1)))
    ).toList();
    
    final allFolic = _prefsService!.getObjectList(SharedPreferencesService.keyFolicAcid);
    final folicAcidRecords = allFolic.where((f) => 
      f['user_id'] == userId &&
      DateTime.tryParse(f['date'] ?? '') != null &&
      DateTime.parse(f['date']).isAfter(startDate.subtract(Duration(days: 1))) &&
      DateTime.parse(f['date']).isBefore(endDate.add(Duration(days: 1)))
    ).toList();
    
    // 转换为按日期索引的映射
    final tempByDate = { for (var e in temperatures) DateFormat('yyyy-MM-dd').format(DateTime.parse(e['date'] ?? '')) : BasalBodyTemperature.fromMap(e) };
    
    final testByDate = { for (var e in ovulationTests) DateFormat('yyyy-MM-dd').format(DateTime.parse(e['date'] ?? '')) : OvulationTest.fromMap(e) };
    
    final mucusByDate = { for (var e in mucusRecords) DateFormat('yyyy-MM-dd').format(DateTime.parse(e['date'] ?? '')) : CervicalMucus.fromMap(e) };
    
    final intercourseByDate = { for (var e in intercourseRecords) DateFormat('yyyy-MM-dd').format(DateTime.parse(e['date'] ?? '')) : Intercourse.fromMap(e) };
    
    final folicByDate = { for (var e in folicAcidRecords) DateFormat('yyyy-MM-dd').format(DateTime.parse(e['date'] ?? '')) : FolicAcidIntake.fromMap(e) };
    
    // 获取周期信息以确定经期日期
    final allPeriods = _prefsService!.getObjectList(SharedPreferencesService.keyPeriods);
    final periods = allPeriods.where((p) => p['user_id'] == userId).map((p) => Period.fromMap(p)).toList();
    final periodDates = <DateTime>{};
    for (var period in periods) {
      for (int i = 0; i < period.length; i++) {
        periodDates.add(period.startDate.add(Duration(days: i)));
      }
    }
    
    // 生成日历数据
    DateTime current = startDate;
    while (current.isBefore(endDate) || current.isAtSameMomentAs(endDate)) {
      final dateStr = DateFormat('yyyy-MM-dd').format(current);
      final isToday = DateFormat('yyyy-MM-dd').format(current) == 
                     DateFormat('yyyy-MM-dd').format(DateTime.now());
      final isOvulation = prediction.predictedOvulationDate.year == current.year &&
                         prediction.predictedOvulationDate.month == current.month &&
                         prediction.predictedOvulationDate.day == current.day;
      final isFertile = prediction.fertileWindow.any((date) =>
                         date.year == current.year &&
                         date.month == current.month &&
                         date.day == current.day);
      final isPeriod = periodDates.any((date) =>
                       date.year == current.year &&
                       date.month == current.month &&
                       date.day == current.day);
      
      calendarDays.add(FertilityCalendarDay(
        date: current,
        isToday: isToday,
        isPredictedOvulation: isOvulation,
        isFertile: isFertile,
        isPeriod: isPeriod,
        pregnancyProbability: prediction.getPregnancyProbabilityForDate(current) * 100,
        temperature: tempByDate[dateStr],
        ovulationTest: testByDate[dateStr],
        cervicalMucus: mucusByDate[dateStr],
        intercourse: intercourseByDate[dateStr],
        folicAcid: folicByDate[dateStr],
      ));
      
      current = current.add(Duration(days: 1));
    }
    
    return calendarDays;
  }

  // 私有辅助方法
  
  // 分析排卵日（基于基础体温变化、宫颈粘液和排卵试纸数据的综合分析）
  Future<void> _analyzeOvulationDays(int userId) async {
    // 获取基础体温数据
    final allTemps = _prefsService!.getObjectList(SharedPreferencesService.keyBBTRecords);
    final temperatures = allTemps.where((t) => t['user_id'] == userId).take(30).toList();
    
    // 获取宫颈粘液数据
    final allMucus = _prefsService!.getObjectList(SharedPreferencesService.keyCMRecords);
    final mucusRecords = allMucus.where((m) => m['user_id'] == userId).take(30).toList();
    
    // 获取排卵试纸数据
    final allTests = _prefsService!.getObjectList(SharedPreferencesService.keyOvulationTests);
    final ovulationTests = allTests.where((t) => t['user_id'] == userId).take(30).toList();
    
    // 如果基础体温数据不足，无法进行分析
    if (temperatures.length < 7) return;

    // 排序体温记录
    final sortedTemps = temperatures.map((t) => BasalBodyTemperature.fromMap(t))
      .toList()..sort((a, b) => a.date.compareTo(b.date));
      
    // 排序宫颈粘液记录
    final sortedMucus = mucusRecords.map((m) => CervicalMucus.fromMap(m))
      .toList()..sort((a, b) => a.date.compareTo(b.date));
      
    // 排序排卵试纸记录
    final sortedTests = ovulationTests.map((t) => OvulationTest.fromMap(t))
      .toList()..sort((a, b) => a.date.compareTo(b.date));
      
    // 创建日期到记录的映射，方便快速查找
    final mucusByDate = { for (var m in sortedMucus) DateFormat('yyyy-MM-dd').format(m.date) : m };
    final testByDate = { for (var t in sortedTests) DateFormat('yyyy-MM-dd').format(t.date) : t };

    // 寻找体温上升的模式（排卵后基础体温通常会上升0.3-0.5°C）
    // 同时考虑宫颈粘液变化和排卵试纸结果
    for (int i = 3; i < sortedTemps.length; i++) {
      final currentTemp = sortedTemps[i];
      final currentDate = DateFormat('yyyy-MM-dd').format(currentTemp.date);
      final previousDate = DateFormat('yyyy-MM-dd').format(currentTemp.date.subtract(Duration(days: 1)));
      
      // 计算前3天的平均体温
      double avgPreviousTemp = 0;
      for (int j = 1; j <= 3; j++) {
        avgPreviousTemp += sortedTemps[i - j].temperature;
      }
      avgPreviousTemp /= 3;

      // 检查体温上升模式
      bool temperaturePattern = currentTemp.temperature > avgPreviousTemp + 0.3;
      
      // 检查宫颈粘液变化模式
      bool mucusPattern = false;
      // 排卵前宫颈粘液通常变为蛋清状，排卵后可能变稠或减少
      if (mucusByDate.containsKey(previousDate)) {
        final previousMucus = mucusByDate[previousDate]!;
        mucusPattern = previousMucus.consistency == 'eggwhite';
      }
      
      // 检查排卵试纸模式
      bool testPattern = false;
      // LH峰值通常在排卵前12-36小时
      if (testByDate.containsKey(previousDate) || testByDate.containsKey(currentDate)) {
        final testDayBefore = testByDate[previousDate];
        final testSameDay = testByDate[currentDate];
        testPattern = (testDayBefore?.isPeakDay() ?? false) || (testSameDay?.isPeakDay() ?? false);
      }
      
      // 综合判断排卵日
      // 优先级：排卵试纸强阳性 > 体温+宫颈粘液变化 > 单一体温变化
      bool isOvulationDay = false;
      DateTime? ovulationDate;
      
      if (testPattern) {
        // 如果有LH峰值，排卵通常发生在峰值后12-36小时
        ovulationDate = currentTemp.date.subtract(Duration(days: testByDate.containsKey(previousDate) ? 0 : 1));
        isOvulationDay = true;
      } else if (temperaturePattern) {
        // 如果体温上升，结合宫颈粘液数据进行判断
        if (mucusPattern) {
          // 体温上升且前一天有蛋清状粘液，强烈提示排卵
          ovulationDate = currentTemp.date.subtract(Duration(days: 1));
          isOvulationDay = true;
        } else if (i >= 4) {
          // 单纯体温上升，仍标记为可能的排卵日
          ovulationDate = currentTemp.date.subtract(Duration(days: 1));
          isOvulationDay = true;
        }
      }
      
      if (isOvulationDay && ovulationDate != null) {
        // 使用非空断言，因为我们已经检查过
        final nonNullOvulationDate = ovulationDate;
        
        // 标记可能的排卵日
        final potentialOvulationDay = sortedTemps.firstWhere(
          (temp) => temp.date.year == nonNullOvulationDate.year && 
                     temp.date.month == nonNullOvulationDate.month && 
                     temp.date.day == nonNullOvulationDate.day,
          orElse: () => sortedTemps.isNotEmpty ? sortedTemps[0] : BasalBodyTemperature(id: 0, date: DateTime.now(), temperature: 0.0, userId: userId) // 安全处理
        );
        
        // 查找记录索引
        final index = temperatures.indexWhere((t) => t['id'] == potentialOvulationDay.id);
        if (index != -1) {
          temperatures[index]['is_ovulation_day'] = 1;
          // 更新整个列表
          _prefsService!.saveObjectList(SharedPreferencesService.keyBBTRecords, allTemps);
        }
        break;
      }
    }
  }

  // 更新排卵分析
  Future<void> _updateOvulationAnalysis(int userId, DateTime peakDay) async {
    // 当检测到LH峰值时，更新相关分析
    final userProfile = _prefsService!.getObject(SharedPreferencesService.keyUser);
    if (userProfile != null) {
      // 记录LH峰值日以改进未来预测
      final updatedProfile = { ...userProfile, 'last_lh_peak_day': peakDay.toIso8601String() };
      await _prefsService!.saveObject(SharedPreferencesService.keyUser, updatedProfile);
    }
  }

  // 更新叶酸依从率
  Future<double> _updateFolicAcidComplianceRate(int userId) async {
    final folicRecords = _prefsService?.getObjectList(SharedPreferencesService.keyFolicAcid) ?? []
        .where((record) => record['userId'] == userId)
        .take(90)
        .toList();
    
    if (folicRecords.isEmpty) return 0.0;

    int totalDays = folicRecords.length;
    int takenDays = folicRecords.where((record) => record['taken'] == true || record['taken'] == 1).length;
    double complianceRate = takenDays / totalDays;

    // 更新用户进度记录
    final userProfile = _prefsService?.getObject(SharedPreferencesService.keyUser);
    if (userProfile != null) {
      final updatedProfile = { ...userProfile, 'folic_acid_compliance_rate': complianceRate };
      await _prefsService?.saveObject(SharedPreferencesService.keyUser, updatedProfile);
    }
    
    return complianceRate;
  }

  // 使用体温数据优化排卵预测
  DateTime _optimizeOvulationPredictionWithTemperature(
    DateTime predictedDate, 
    List<Map<String, dynamic>> temperatures) {
    // 已确保非空，无需额外检查
    if (temperatures.isEmpty) return predictedDate;

    final sortedTemps = temperatures.map((t) => BasalBodyTemperature.fromMap(t))
      .toList()..sort((a, b) => b.date.compareTo(a.date)); // 最新的在前

    // 检查是否有近期的体温上升模式
    for (int i = 0; i < math.min(5, sortedTemps.length - 1); i++) {
      if (sortedTemps[i].temperature > sortedTemps[i + 1].temperature + 0.3) {
        // 发现体温上升，可能已经排卵
        return sortedTemps[i + 1].date; // 排卵可能发生在前一天
      }
    }

    return predictedDate;
  }

  // 使用排卵试纸数据优化预测
  DateTime _optimizeOvulationPredictionWithTests(
    DateTime predictedDate, 
    List<Map<String, dynamic>> tests) {
    if (tests.isEmpty) return predictedDate;

    final sortedTests = tests.map((t) => OvulationTest.fromMap(t))
      .toList()..sort((a, b) => b.date.compareTo(a.date));

    // 寻找最新的阳性或强阳性测试
    for (var test in sortedTests) {
      if (test.isPeakDay()) {
        // LH峰值后12-36小时内可能排卵
        return test.date.add(Duration(hours: 24));
      }
    }

    return predictedDate;
  }

  // 使用宫颈粘液数据优化预测
  DateTime _optimizeOvulationPredictionWithMucus(
    DateTime predictedDate, 
    List<Map<String, dynamic>> mucusRecords) {
    if (mucusRecords.isEmpty) return predictedDate;

    final sortedMucus = mucusRecords.map((m) => CervicalMucus.fromMap(m))
      .toList()..sort((a, b) => b.date.compareTo(a.date));

    // 寻找最新的蛋清状粘液（受孕最友好的类型）
    for (var mucus in sortedMucus) {
      if (mucus.consistency == 'eggwhite') {
        // 蛋清状粘液通常出现在排卵前后
        return mucus.date.add(Duration(days: 1));
      }
    }

    return predictedDate;
  }

  // 计算峰值受孕概率
  double _calculatePeakProbability(
    List<Map<String, dynamic>> temperatures,
    List<Map<String, dynamic>> ovulationTests,
    List<Map<String, dynamic>> mucusRecords,
    int periodCount,
  ) {
    // 基础概率
    double baseProbability = 0.25; // 约25%

    // 根据数据完善程度调整概率
    if (temperatures.length >= 30) baseProbability += 0.05;
    if (ovulationTests.any((t) => OvulationTest.fromMap(t).isPeakDay())) {
      baseProbability += 0.10;
    }
    if (mucusRecords.any((m) => CervicalMucus.fromMap(m).consistency == 'eggwhite')) {
      baseProbability += 0.05;
    }
    if (periodCount >= 6) baseProbability += 0.05;

    // 限制最大值
    return math.min(baseProbability, 0.40); // 最高约40%
  }

  // 计算预测置信度
  int _calculateConfidence(
    List<Period> periods,
    List<Map<String, dynamic>> temperatures,
    List<Map<String, dynamic>> ovulationTests,
    List<Map<String, dynamic>> mucusRecords,
  ) {
    int confidence = 50; // 基础置信度50%

    // 周期规律性
    if (periods.length >= 6) {
      final cycleLengths = <int>[];
      for (int i = 0; i < periods.length - 1; i++) {
        cycleLengths.add(periods[i].startDate.difference(periods[i + 1].startDate).inDays);
      }
      
      if (cycleLengths.isNotEmpty) {
        final avg = cycleLengths.reduce((a, b) => a + b) / cycleLengths.length;
        final variance = cycleLengths.map((len) => math.pow(len - avg, 2))
          .reduce((a, b) => a + b) / cycleLengths.length;
        
        if (variance < 2) {
          confidence += 20; // 非常规律
        } else if (variance < 5) {
          confidence += 10; // 比较规律
        } else if (variance > 10) {
          confidence -= 10; // 不规律
        }
      }
    } else if (periods.length < 3) {
      confidence -= 10; // 数据太少
    }

    // 数据完整性
    if (temperatures.length >= 30) {
      confidence += 10;
    }
    if (ovulationTests.isNotEmpty) {
      confidence += 5;
    }
    if (mucusRecords.isNotEmpty) {
      confidence += 5;
    }

    // 限制范围
    return confidence.clamp(10, 95);
  }

  // 生成推荐建议
  String _generateRecommendation(
    DateTime ovulationDate,
    List<DateTime> fertileWindow,
    double peakProbability,
    int confidence,
  ) {
    final daysUntilOvulation = ovulationDate.difference(DateTime.now()).inDays;
    final recommendations = <String>[];

    // 基于时间的建议
    if (daysUntilOvulation > 7) {
      recommendations.add('您的易孕期将在$daysUntilOvulation天后开始，建议提前做好准备。');
    } else if (daysUntilOvulation >= 0) {
      recommendations.add('您的易孕期将在$daysUntilOvulation天后开始，现在是增加同房频率的好时机。');
    } else if (fertileWindow.any((date) => 
        date.year == DateTime.now().year &&
        date.month == DateTime.now().month &&
        date.day == DateTime.now().day)) {
      recommendations.add('您现在处于易孕期，受孕概率较高。');
    } else {
      recommendations.add('您的易孕期已过，等待下一个周期。');
    }

    // 基于数据的建议
    if (confidence < 60) {
      recommendations.add('为提高预测准确性，建议继续记录基础体温、排卵试纸和宫颈粘液情况。');
    }

    // 基于概率的建议
    if (peakProbability > 0.30) {
      recommendations.add('本周期受孕概率较高，建议在排卵日前后增加同房频率。');
    } else {
      recommendations.add('保持规律的生活作息和健康饮食，有助于提高受孕几率。');
    }

    return recommendations.join(' ');
  }
}